﻿<?php

//////////////////////////////////////////////////////////////////////////
//
// WikiHiero2 - A PHP convert from text using "Manual for the encoding of
// hieroglyphic texts for computer input" syntax to HTML entities (table and
// images).
//
// Copyright (C) 2004-2007 Guillaume Blanchard (Aoineko)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
//////////////////////////////////////////////////////////////////////////

require_once("wh_tools.php");
require_once("wh_class.php");

////////////////////////////////////////////////////////////////////////////////
/**
 * WikiHiero Attribute class
 */
class WH_Attribute
{
	// Auto-generated
	const Id          = "id";        // *
	const Level       = "level";     // area, section
	// Special
	const Content     = "content";   // area, line, section, desc
	// Generic
	const Type        = "type";      // area, section, lexeme, desc
	const Name        = "name";      // document, area, section, reference
	const Reference   = "ref";       // section, sentence, word, lexeme
	const Langage     = "xml::lang"; // reference, desc (for value, see: http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)
	// Specific
	const Title       = "title";     // reference
	const Author      = "author";    // reference
	const Publisher   = "publisher"; // reference
	const Address     = "address";   // reference
	const Year        = "year";      // reference
	const Page        = "page";      // desc
	const Paragraph   = "paragraph"; // desc	
	const Direction   = "dir";       // line
	const Orientation = "orient";    // line
	const Operator    = "op";        // group
	const Code        = "code";      // hiero
	const Phoneme     = "phoneme";   // hiero
	const Source      = "source";    // desc
	const Position    = "pos";       // area
	const Size        = "size";      // area
	
	static $AreaType = array
	(
		1 => "book",
		2 => "tome",
		3 => "page",
		10 => "stela",
		11 => "register",
	);
}


////////////////////////////////////////////////////////////////////////////////
/**
 * WikiHiero Node class
 */
class WH_Node
{
	protected $class;      // Class of the node (doc, page, row, etc.). See WH_CLASS_*.
	protected $attributes; // List of the node attributes.
	protected $children;   // List of the node children.
	protected $parent;     // Parent node.
	
	static protected $uid = 0; // Static incremental index

	////////////////////////////////////////////////////////////////////////////////
	/**
	 * Constructor.
	 * @param	$class	The node's class constructor.
	 */
	public function __construct($parent, $class)
	{
		$this->class      = $class;
		$this->parent     = $parent;
		$this->attributes = array();
		$this->children   = array();
		if(WH_Document::IsClassReferenced($class))
			$this->SetAttribute(WH_Attribute::Id, WH_Node::$uid++);
	}
	
	// firstChild
	// childNodes[0]
	// lastChild

	////////////////////////////////////////////////////////////////////////////////
	/**
	 * Reset index variable
	 */
	static public function ResetIndex()
	{
		WH_Node::$uid = 0;
	}

	////////////////////////////////////////////////////////////////////////////////
	/**
	 * Get the node's parent.
	 * @return			The node's parent.
	 */
	public function &GetParent()
	{
		return $this->parent;
	}

	////////////////////////////////////////////////////////////////////////////////
	/**
	 * Get the node's number a children.
	 * @return			The node's class.
	 */
	public function GetClass()
	{
		return $this->class;
	}
	////////////////////////////////////////////////////////////////////////////////
	/**
	 * Add a child to the node.
	 * @param	$class	The child's class.
	 * @return			The created node.
	 */
	public function &AddChild($class)
	{
		global $wh_class;
		if(!in_array($this->class, $wh_class[$class]["Owners"]))
			WH_Assert("Class [".WH_GetClassName($class)."] can't be created in parent of type [".WH_GetClassName($this->class)."]");
		$this->children[] = new WH_Node($this, $class);
		return $this->children[count($this->children) - 1];
	}
	
	////////////////////////////////////////////////////////////////////////////////
	/**
	 * Get the children array.
	 * @return			The children array.
	 */
	public function &GetChildren()
	{
		return $this->children;
	}

	////////////////////////////////////////////////////////////////////////////////
	/**
	 * Get the node's number a children.
	 * @return			The number of node's children.
	 */
	public function GetChildNumber()
	{
		return count($this->children);
	}

	////////////////////////////////////////////////////////////////////////////////
	/**
	 * Get a given node's child.
	 * @param	$index	The index of the given node's child.
	 * @return			The given node's child.
	 */
	public function &GetChild($number)
	{
		if(!isset($this->children[$number]))
			HW_Error("Try to access an inexisting node's child! Index=$index");
		return $this->children[$number];
	}

	////////////////////////////////////////////////////////////////////////////////
	/**
	 * Get a given node's child.
	 * @param	$index	The index of the given node's child.
	 */
	public function RemoveChild($child)
	{
		unset($this->children[$child]);
	}

	////////////////////////////////////////////////////////////////////////////////
	/**
	 * Set attribute to the node.
	 * @param	$att	Attribute to set.
	 * @param	$val	Attribute value.
	 */
	public function SetAttribute($att, $val)
	{
		$this->attributes[$att] = $val;
	}

	////////////////////////////////////////////////////////////////////////////////
	/**
	 * Get the attributes array.
	 * @return			The attributes array.
	 */
	public function &GetAttributes()
	{
		return $this->attributes;
	}

	////////////////////////////////////////////////////////////////////////////////
	/**
	 * Get the node's number of attribute(s).
	 * @return			The number of attribute(s).
	 */
	public function GetAttributeNumber()
	{
		return count($this->attributes);
	}

	////////////////////////////////////////////////////////////////////////////////
	/**
	 * Get attribute from the node.
	 * @param	$index	The index of the given node's attribute.
	 * @return			The given node's attribute.
	 */
	public function &GetAttribute($key)
	{
		if(!isset($this->attributes[$key]))
			WH_Error("Try to access an inexsting node's attribute! Index=$key");
		return $this->attributes[$key];
	}

	////////////////////////////////////////////////////////////////////////////////
	/**
	 * Tell if a given attribute is set.
	 * @param	$index	The index of the given node's attribute.
	 * @return			'true' if attribute set, 'false' otherwise.
	 */
	public function IsAttributeSet($index)
	{
		return isset($this->attributes[$index]);
	}
}

?>